<script setup lang="ts">
import type { ComponentDefinition, ComponentDefinitionItem } from '@/definitions/type'
import AsideToggler from '@/components/AsideToggler/AsideToggler.vue'
import { componentDefinitions } from '@/definitions/component-definition'
import { useDesignStore } from '@/stores'
import { withPublicPath } from '@/utils/publicPath'
import { Popover } from 'ant-design-vue'
import { markRaw, ref } from 'vue'
import { VueDraggable } from 'vue-draggable-plus'
import { usePopupPreview } from './usePopupPreview'

defineOptions({
  name: 'Aside',
})
const designStore = useDesignStore()
const { mouseEnter, mouseLeave, popoverImg, popoverVisible } = usePopupPreview()

const compDefs = markRaw(componentDefinitions)
const activeComponentDefinition = ref<ComponentDefinition>(componentDefinitions[0])
function handleChangeDef(def: ComponentDefinition) {
  activeComponentDefinition.value = def
}
function customClone(element: ComponentDefinitionItem) {
  return designStore.customDragClone(element)
}
</script>

<template>
  <div class="fixed left-0 top-[var(--app-nav-bar-height)] bottom-0 box-border flex z-[var(--app-aside-zindex)] aside-pannel" :class="designStore.asideTogglerOpened ? '' : 'collapsed'">
    <!-- aside category -->
    <div class="flex flex-col py-4 w-[var(--app-aside-bar-width)] bg-[#fafaff] h-full overflow-auto">
      <div
        v-for="item of compDefs" :key="item.category"
        class="flex relative flex-col gap-2 py-4 justify-center items-center text-main-app hover:text-primary-app cursor-pointer aside-category"
        :class="item.category === activeComponentDefinition.category ? 'active' : ''" @click="handleChangeDef(item)"
      >
        <i class="w-6 h-6" :class="item.icon" />
        <span class="text-base">{{ item.text }}</span>
      </div>
    </div>
    <!-- category components -->
    <div class="w-[var(--app-aside-bar-comps-width)] h-full px-4 overflow-auto bg-white relative components-aside">
      <VueDraggable
        v-model="activeComponentDefinition.items" :animation="150"
        :group="{ name: 'component', pull: 'clone', put: false }" :sort="false" :clone="customClone"
        class="flex flex-row flex-wrap justify-between"
      >
        <div
          v-for="item in activeComponentDefinition.items" :key="item.name"
          class="flex-none w-88px h-[fit-content] cursor-move component-item" @mouseenter="mouseEnter(withPublicPath(item.vewPicture!))"
          @mouseleave="mouseLeave"
        >
          <img
            :src="withPublicPath(item.thumb!)" alt="" class="block w-88px h-88px rounded-sm object-contain component-item-img"
            :width="88" :height="88"
          >
          <div class="leading-7 text-center truncate">
            {{ item.name }}
          </div>
        </div>
      </VueDraggable>
    </div>
    <!-- component preview popover -->
    <Popover placement="rightTop" :open="popoverVisible">
      <template #content>
        <img :src="popoverImg" alt="component preview" :width="64" :height="64" class="block w-64 h-64 object-contain">
      </template>
      <div class="popover-refrence" />
    </Popover>
    <!-- toggle -->
    <AsideToggler />
  </div>
</template>

<style lang="less" scoped>
.aside-pannel {
  transition: 0.1s;
  transform: translate3d(0, 0, 0);
  &.collapsed {
    transform: translate3d(-100%, 0, 0);
  }
}
.aside-category {
  &.active {
    background-color: white;
    color: var(--app-color-primary);
  }

  &::after {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
  }

  &.active::after {
    background-color: var(--app-color-primary);
  }
}

.component-item {
  &:hover {
    .component-item-img {
      border: 1px solid var(--app-color-primary);
    }
  }
}

.components-aside {
  box-shadow: 4px 0 8px rgba(0, 0, 0, .05);
}

.popover-refrence {
  position: absolute;
  right: 0;
  top: 30px;
  width: 5px;
  height: 5px;
  background-color: transparent;
}
</style>
